/*******************************************************************************
    文件名称： 
	开发者：孙磊
	开发时间地点：2013.12.5 于郑州
	邮箱：zhongyuansunlei@163.com
	版本信息：
		
********************************************************************************/
#include <string.h>
#include <stdlib.h>
#include "queue.h"


int iinit_queue(queue **ppq, int isize)
{
	queue *p;
	
	p = (queue*)malloc(sizeof(queue));
	if(p == NULL) {
		return RC_NOSPACE;
	}
	
	memset(p, 0, sizeof(queue));
	p->m_pbase = (queue_elem*)malloc(sizeof(queue_elem)*isize);
	if(p->m_pbase == NULL){
		return RC_NOSPACE;
	}
	p->m_iactualused = 1; 	
	p->m_itotalnum = isize;
	*ppq = p;
		
	return 0;
}

int ien_queue(queue* pq, void* pvalue, int (*mem_alloc_cp_func)(queue_elem*, void*))
{
	queue_elem* p;
	if((pq->m_iactualused > pq->m_icur)&&((pq->m_iactualused - pq->m_icur+1) >pq->m_itotalnum))  {
		return -1;
	}
	
	if((pq->m_iactualused + 1) == pq->m_icur) {
		return -1;
	}
	
	if(pq->m_iactualused !=0) {
		p = (queue_elem*)(&pq->m_pbase[pq->m_iactualused-1]);
	} else {
		p = (queue_elem*)(&pq->m_pbase[pq->m_itotalnum-1]);
	}
	
	if(mem_alloc_cp_func(p, pvalue) < 0) {
		return -1;
	}
	
	if((pq->m_iactualused+1) > pq->m_itotalnum) {
		pq->m_iactualused = 0;
	} else 
		pq->m_iactualused++;
	
	return 0;

}


queue_elem *pde_queue(queue* pq)
{
	if(pq->m_iactualused ==(1+pq->m_icur)) 
		return NULL;
	
	if((pq->m_iactualused == 0)&& (pq->m_icur == (pq->m_itotalnum - 1)))
		return NULL;
	
	
	int icur = pq->m_icur++;
	if(icur == pq->m_itotalnum)
		icur = 0;
	
	return &(pq->m_pbase[icur]);
}

void vreset_queue(queue* pq)
{
	pq->m_icur = pq->m_iactualused = 0;
	return ;
}

int irelease_queue(queue* pq, void (*free_func)(void*))
{
	for(int i=0;i<pq->m_iactualused;i++) {
		free_func((void*)(&pq->m_pbase[i]));
	}
	
	free(pq->m_pbase);
	free(pq);
}

void vprint_queue(queue* pq, void (*print_func)(void*))
{
	queue_elem* pe;
	int i = pq->m_icur;
	for(;i<pq->m_iactualused;i++)
	{
		pe =( &(pq->m_pbase[i]));
		print_func(pe->m_pval);
	}	
}


int iget_queue_num(queue* pq)
{
	return (pq->m_iactualused - pq->m_icur);
}
